<?php
/**
 * Model for a project.
 *
 * @category PhpCilux
 * @package  PhpCilux
 */

/**
 * Model for a project.
 *
 * @package PhpCilux
 */
class Model_Project
{

    /**
     * The project key of this project.
     *
     * @var string
     */
    protected $_projectKey;

    /**
     * The source dir.
     *
     * @var string
     */
    protected $_srcDir;

    /**
     * Constructor.
     *
     * @param array $options Several options (key -> value).
     */
    public function __construct(array $options = null)
    {
        if (is_array($options)) {
            $this->setOptions($options);
        }
    }

    /**
     * Magic setter.
     *
     * @param mixed $name  The property name.
     * @param mixed $value The property value.
     *
     * @return void
     * @throws Exception Invalid property.
     */
    public function __set($name, $value)
    {
        $method = 'set' . $name;
        if (!method_exists($this, $method)) {
            throw new Exception('Invalid property');
        }

        $this->$method($value);
    }

    /**
     * Magic getter.
     *
     * @param mixed $name The property name.
     *
     * @return mixed The value.
     * @throws Exception Invalid property.
     */
    public function __get($name)
    {
        $method = 'get' . $name;
        if (!method_exists($this, $method)) {
            throw new Exception('Invalid property');
        }

        return $this->$method();
    }

    /**
     * Set several options.
     *
     * @param array $options Several options (key -> value).
     *
     * @return Model_Project
     */
    public function setOptions(array $options)
    {
        $methods = get_class_methods($this);
        foreach ($options as $key => $value) {
            $method = 'set' . (str_replace(' ', '', ucwords(str_replace('_', ' ', $key))));
            if (in_array($method, $methods)) {
                $this->$method($value);
            }
        }

        return $this;
    }

    /**
     * Set the project key.
     *
     * @param string $text The project key.
     *
     * @return Model_Project
     */
    public function setProjectKey($text)
    {
        $this->_projectKey = (string) $text;
        return $this;
    }

    /**
     * Get the project key.
     *
     * @return string
     */
    public function getProjectKey()
    {
        return $this->_projectKey;
    }

    /**
     * Get the current build status.
     *
     * @return string
     * @throws Exception Uncatched exceptions.
     */
    public function getBuildStatus()
    {
        try {
            $status = $this->getLastBuild()->getStatus();
        } catch (Exception $e) {

            if ('Can not find build' != $e->getMessage()) {
                throw $e;
            }

            $status = 'nobuild';
        }

        return $status;
    }

    /**
     * Get the name of the project.
     *
     * @return string
     */
    public function getName()
    {
        return $this->getProjectKey();
    }

    /**
     * Get the last build.
     * 
     * @return Model_Build
     * @throws Exception No build found.
     */
    public function getLastBuild()
    {
        $build = Model_BuildMapper::getInstance()->getLast($this->_projectKey);

        if ($build instanceof Model_Build) {
            return $build;
        }

        throw new Exception('Can not find build');
    }

    /**
     * Get a build by the given build key.
     * 
     * @param string $buildKey A build key.
     *
     * @return Model_Build
     * @throws Exception No build found.
     */
    public function getBuild($buildKey)
    {
        $build = Model_BuildMapper::getInstance()->getBuild($this->_projectKey, $buildKey);

        if ($build instanceof Model_Build) {
            return $build;
        }

        throw new Exception('Can not find build');
    }

    /**
     * Get the previous build based on the given build key.
     *
     * @param string  $buildKey A build key.
     * @param integer $limit    Max count of builds.
     *
     * @return array Array of Model_Build
     */
    public function getPrevBuilds($buildKey, $limit = 10)
    {
        return Model_BuildMapper::getInstance()->getPrevBuilds($this->_projectKey, $buildKey, $limit);
    }

    /**
     * Set the source dir.
     *
     * @param string $text The source dir.
     *
     * @return Model_Project
     */
    public function setSrcDir($text)
    {
        $this->_srcDir = (string) $text;
        return $this;
    }

    /**
     * Get the source dir.
     * 
     * @return string
     */
    public function getSrcDir()
    {
        return $this->_srcDir;
    }

}